/* 
 * File:   test.cpp
 * Author: rodriguj
 * 
 * Created on June 6, 2012, 10:36 AM
 */
#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

typedef struct QUERY_RESULT {
	double score;
	unsigned long docId;
	char* url;
} RESULT;

// callback signature
typedef int (*Callback)(unsigned int, unsigned int, QUERY_RESULT*); 

class Foo{

	unsigned int top_k;
	QUERY_RESULT* results;
	
	int get_results()
	{
		QUERY_RESULT* r = results;
		
		// send 'k' or less results back
		r->score = 1.2;
		r->docId = 1;
		string s1 = "CLUEWEB1";
		r->url = "CLUEWEB1";
		
		r++;
		r->score = 23.1;
		r->docId = 2;
		string s2 = "CLUEWEB2";
		r->url = "CLUEWEB2";
		
		r++;
		r->score = 3.21;
		r->docId = 4;
		string s3 = "CLUEWEB3";
		r->url = "CLUEWEB3";
		r++;
		
		// null terminate the list
		r->score = 0;
		r->docId = 0;
		r->url = NULL;
		
		// return actual # of results
		return 3;
	}
	
    public:
	
		Foo(unsigned int);
        ~Foo();
		
        // schedule the query processing
        void push(unsigned int id, char *arg, Callback callback){
            std::cout << "query " << id << ": " << arg << std::endl;
            
            //  dome some work ... this can be async:
			int k = get_results();
			
            // signal results are ready
            callback(id, k, results);
        }
};

Foo::Foo(unsigned int top_k)
{
	results = (QUERY_RESULT*) malloc(sizeof(QUERY_RESULT) * (top_k+1));
}

Foo::~Foo()
{
	free(results);
}

extern "C" {
    Foo* Foo_new(unsigned int top_k){ 
        return new Foo(top_k); 
    }

	void Foo_delete(Foo* foo) {
		delete foo;
	}

	void Foo_push(Foo* foo, unsigned int id, char *arg, Callback callback){ 
        foo->push(id,arg,callback);
    }
	
}

